#include <stdio.h>
#include <stdlib.h>     //exit()
#include <string.h>
#include <errno.h>
#include <fcntl.h>      // 非阻塞宏
#include <sys/ioctl.h>
#include <sys/epoll.h>  // epoll管理服务器的连接和接收触发
#include <sys/socket.h>
#include <netinet/ip.h>
#include <pthread.h>    // 使用多线程
#include "websocket_common.h"

#define		EPOLL_RESPOND_NUM		10	// epoll最大同时管理句柄数量
extern int webSocket_clientLinkToServer(char *ip, int port, char *interface_path);
extern int webSocket_serverLinkToClient(int fd, char *recvBuf, int bufLen);
extern int webSocket_recv(int fd, DynBuf *pdata, WebsocketData_Type *dataType);
typedef struct{
    int fd;
    int client_fd_array[EPOLL_RESPOND_NUM][2];//客户句柄数据
    char ip[24];
    int port;
   
    CallBackFun callBack;
    CallCloseedFun callCloseed;
}WebSocket_Client;

WebSocket_Client m_wsc;


/*****************************************************************
 * 添加值到数据组中
 * 参数：array[][2]数组
 *      arraySize数组大小
 *      value:值
 * 返回：0 成功，-1失败
*****************************************************************/
int c_arrayAddItem(int array[][2], int arraySize, int value)
{
    int i;
    for(i = 0; i < arraySize; i++)
    {
        if(array[i][1] == 0)
        {
            array[i][0] = value;
            array[i][1] = 1;
            return 0;
        }
    }
    return -1;
}
/*************************************************************
 * 从数组中移除值
 * 返回值： >=0 成功 序号 -1失败
***********************************************************/
int c_arrayRemoveItem(int array[][2], int arraySize, int value)
{
    int i;
    for(i = 0; i < arraySize; i++)
    {
        if(array[i][0] == value)
        {
            array[i][0] = 0;
            array[i][1] = 0;
            return i;
        }
    }
    return -1;
}
/************************************************************
 * 再找项
*/
int c_arrayFindItem(int array[][2], int arraySize, int value)
{
    int i;
    for(i = 0; i < arraySize; i++)
    {
        if(array[i][0] == value)
        {
            return i;
        }
    }
    return -1;
}
/*********************************
 * 再找项
 *
 * **********************************/
int c_arrayFindNickname(char *array[], int arraySize, char *value)
{
    int i;
    for(i = 0; i < arraySize; i++)
    {
        if(strlen(array[i])>0)
        if((strstr(array[i],value)!=NULL)&&(strstr(array[i],value)==array[i]))
        {
            return i;
        }
    }
    return -1;
}


/******************************************
*套接字监控进程
*****************************************/
void* client_thread_fun(void *arge)
{
    int ret ,timeCount = 0;
    DynBuf buf;
    webSocket_bufInit(&buf,RECV_BYTE_LEN);

    WebSocket_Client *wsc = (WebSocket_Client *)arge;


        printf("\r\n\r\n========== client webSocket start ! ==========\r\n\r\n");
    while(1)
    { 




            //===================接收数据事件===================

                webSocket_bufReset(&buf);
                WebsocketData_Type datatype;
                ret = webSocket_recv(wsc->fd , &buf, &datatype);    // 使用websocket recv
                if(ret > 0)
	            {
                    /*
		            printf("client(fd/%d) recv:\r\n"
                        "数据类型：%d\r\n"
                        "数据长度byte:%d\r\n"
                        "内容：\r\n%s\r\n"
                        , events[j].data.fd,datatype,ret, wsc->buf);	*/
                    if(wsc->callBack!=NULL){
                        wsc->callBack(wsc->fd,datatype,buf.data,ret);

                    }


	            }
                    else if(ret <= 0)// 检查错误, 是否连接已断开
                    {
                          if(errno == EAGAIN || errno == EINTR);
                            else if(ret==0)
                            {
                              if(wsc->callCloseed!=NULL)
                                  wsc->callCloseed(wsc->fd);
                                break;
                            }
                            else
                            {
                                printf("其它未处理数据 ret=%d,errno=%d\n",ret,errno);
                            }
                            
                    }
                
                 webSocket_delayms(10);
                timeCount += 10;
               /* if(timeCount >= 1000*60) /////////////////////////////////////// 每4s 客户端可以在这里定时骚扰一下服务器
                {
                    timeCount = 0;
                    ret = webSocket_send(wsc->fd, "PING", strlen("PING"), true, WDT_PING);
                    if(ret <= 0)
                    {
                        break;
                    }
                }*/


    }
    webSocket_bufFree(&buf);	
    //关闭socket
    close(wsc->fd);
}
/******************************************
 * 客户端初始化
 * 返回：句柄fd
 * ***************************************/
int client_init(char *ip, int port, char *interface_path,CallBackFun *client_callBack,CallCloseedFun *client_callCloseed)
{
    int fd;
    if((fd = webSocket_clientLinkToServer(ip, port, "/null")) <= 0)
    {
        printf("client link to server failed !\r\n");
        return -1;
    }
    //===== 初始化参数 =====
    memset(&m_wsc, 0, sizeof(m_wsc));  
    m_wsc.callBack = client_callBack; // 响应客户, 需要干嘛?
    m_wsc.callCloseed=client_callCloseed;
    m_wsc.fd=fd;
    pthread_t client_thread_id;
    //===== 开辟线程, 管理服务器回调 =====
    if(pthread_create(&client_thread_id, NULL, client_thread_fun, (void *)(&m_wsc)) != 0)
	{
		printf("创建线程失败!\r\n");
		return 0;
	} 
    //pthread_cancel(client_thread_id);     // 等待线程关闭
    return fd;
}
